
package ploy.library;

import java.io.*;
import java.text.*;

import ploy.lang.*;
import ploy.compiler.*;

public class Load extends Closure {

    private SyntacticEnvironment syntacticEnvironment;

    public Load( SyntacticEnvironment se ) {
	super( 1 );
	syntacticEnvironment = se;
    }

    /** Reads whitespace, and returns nothing. */
    static private void eatWhitespace( PushbackReader r ) 
	throws IOException 
    {
	char c;
	do {
	    c = (char)r.read();
	} while ( ( c != -1 ) && ( Character.isWhitespace( c ) ) );
	if ( c != -1 ) r.unread( c );
    }

    /** Given an AST, compiles and invokes it. */
    public static void invokeAST( AST a ) 
	throws ParseException, RuntimeError
    {
        Closure closure = AST.compileThunk( a, AST.ployClassLoader );
	
        DynamicObject result = closure.invoke0( );
        System.out.println( result.toString() );
    }
 
    public DynamicObject invoke1( DynamicObject s1 ) 
	throws RuntimeError
    {
	if ( !(s1.isString()) )
	    throw new RuntimeError( "Bad filename: " + s1.toString() );
	
	String filename = ((DString)s1).getStringValue();

	PushbackReader inPb;
	try {
	    inPb = 
		new PushbackReader( new InputStreamReader( new FileInputStream(  filename ) ) );
	} catch ( FileNotFoundException e ) {
	    throw new RuntimeError( "File not found: " + filename );
	}

	DynamicObject nextSexp;
	AST nextAST;

	for ( ; ; ) {

	    try {
		eatWhitespace(inPb);
		char endLooker = (char)inPb.read();
		if ( endLooker == -1 ) {
		    break;
		} else {
		    inPb.unread( endLooker );
		}
		nextSexp = DynamicObject.readSexp( inPb );
		System.out.println( nextSexp.toString( ) );
	    } catch ( IOException e ) {
		System.out.println( "[READ ERROR] " + e.getMessage( ) );
	        break;
	    }
	    try {
		nextAST = AST.parse( nextSexp, syntacticEnvironment );
		System.out.println( nextAST.toString( ) );
		invokeAST( nextAST );
	    } catch ( ParseException p ) {
		System.out.println( "[PARSE ERROR] " + p.getMessage( ) );
		continue;
	    } catch ( RuntimeError c ) {
		System.out.println( "[RUNTIME ERROR] " + c.getMessage( ) );
		continue;
	    }
	}


	return new Nil();
    }
}